%
% Copyright (c) 2010,2013 LAAS/CNRS
% All rights reserved.
%
% Permission to use, copy, modify, and distribute this software for any purpose
% with or without   fee is hereby granted, provided   that the above  copyright
% notice and this permission notice appear in all copies.
%
% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
% REGARD TO THIS  SOFTWARE INCLUDING ALL  IMPLIED WARRANTIES OF MERCHANTABILITY
% AND FITNESS. IN NO EVENT SHALL THE AUTHOR  BE LIABLE FOR ANY SPECIAL, DIRECT,
% INDIRECT, OR CONSEQUENTIAL DAMAGES OR  ANY DAMAGES WHATSOEVER RESULTING  FROM
% LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
% OTHER TORTIOUS ACTION,   ARISING OUT OF OR IN    CONNECTION WITH THE USE   OR
% PERFORMANCE OF THIS SOFTWARE.
%
%                                             Anthony Mallet on Wed Oct 29 2010
%

\section{General operation} % ----------------------------------------------
\label{section:genvars}

\subsection{Adding build options to a package} % ---------------------------
\label{section:genvars:PKG_SUPPORTED_OPTIONS}

Build options (see \xref{section:configuring:build_options}%
{section~\ref{section:configuring:build_options}} for details) can be defined
in a package by properly configuring the following variables.

\begin{description}

   \item[PKG\_SUPPORTED\_OPTIONS]
   This is a list of build options supported by the package. This variable
   should be set in a package Makefile.  E.g.,
\begin{verbatim}
	PKG_SUPPORTED_OPTIONS=	ipv6 ssl
\end{verbatim}
   If this variable is not defined, {\tt PKG\_OPTIONS} is set to the empty list
   and the package is otherwise treated as not using the options framework.

   \smallbreak
   \item[PKG\_OPTION\_DESCR.<opt>]
   This is the textual description of the option <opt> which is displayed by
   the {\tt make show-options} target. E.g.,
\begin{verbatim}
	PKG_OPTION_DESCR.bar=	Enable the bar option.
\end{verbatim}

   \smallbreak
   \item[PKG\_OPTION\_SET.<opt> (resp. PKG\_OPTION\_UNSET.<opt>)]
   This is a makefile fragment that is evaluated when the option <opt> is set
   (resp unset) for the package. E.g.,
\begin{verbatim}
	PKG_OPTION_SET.bar=	CFLAGS+=-DBAR
	PKG_OPTION_UNSET.bar=	CFLAGS+=-DNO_BAR
\end{verbatim}
   Complex (multiline) {\tt \_SET} or {\tt \_UNSET} actions can be defined with
   the {\tt define} command of GNU-make. It is for instance possible to add
   additional dependencies: see the example below.

   \smallbreak
   \item[PKG\_OPTIONS\_OPTIONAL\_GROUPS]
   This is a list of names of groups of mutually exclusive options.  The
   options in each group are listed in {\tt PKG\_OPTIONS\_GROUP.<groupname>}.
   The most specific setting of any option from the group takes precedence over
   all other options in the group.  Options from the groups will be
   automatically added to {\tt PKG\_SUPPORTED\_OPTIONS}.

   \smallbreak
   \item[PKG\_OPTIONS\_REQUIRED\_GROUPS]
   Like {\tt PKG\_OPTIONS\_OPTIONAL\_GROUPS}, but building the packages will
   fail if no option from the group is selected.

   \smallbreak
   \item[PKG\_OPTIONS\_NONEMPTY\_SETS]
   This is a list of names of sets of options.  At least one option from each
   set must be selected. The options in each set are listed in {\tt
   PKG\_OPTIONS\_SET.<setname>}.  Options from the sets will be automatically
   added to {\tt PKG\_SUPPORTED\_OPTIONS}.

   \smallbreak
   \item[PKG\_OPTIONS\_SUFFIX]
   The suffix in {\tt PKG\_OPTIONS.suffix} variable the user can set to enable
   or disable options specifically for this package. Defaults to {\tt
   \$\{PKGBASE\}}.

   \smallbreak
   \item[PKG\_SUGGESTED\_OPTIONS]
   This is a list of build options which are enabled by default. This defaults
   to the empty list.

\end{description}

Here is an example Makefile fragment for a 'wibble' package. This fragment
should be included in the 'wibble' package Makefile.

\begin{verbatim}
	PKG_OPTIONS_SUFFIX=		wibble # this is the default
	PKG_SUPPORTED_OPTIONS=		foo bar
	PKG_OPTIONS_OPTIONAL_GROUPS=	robot
	PKG_OPTIONS_GROUP.robot=	lama hrp2
	PKG_SUGGESTED_OPTIONS=		foo

	PKG_OPTION_DESCR.foo=		Enable the foo option.
	PKG_OPTION_DESCR.bar=		Build with the bar package.
	PKG_OPTION_DESCR.lama=		Build for the lama robot.
	PKG_OPTION_DESCR.hrp2=		Build for the hrp2 robot.

	define PKG_OPTION_SET.bar
	 CFLAGS+=-DNO_BAR
	 include ../../pkg/bar/depend.mk
	endef
	PKG_OPTION_UNSET.bar=		CFLAGS+=-DNO_BAR
\end{verbatim}

\subsection{Customizing the PLIST} % ---------------------------------------
\label{section:genvars:PLIST}

The packing list of a package is usually computed from the {\tt PLIST} file
located in the package directory. The following variables determine how the
final packing list is setup:

\begin{description}

   \item[PLIST\_SRC]
   The source file(s) for the final packing list.  By default, its value
   is constructed from the PLIST.* files within the package directory:
\begin{verbatim}
    PLIST_SRC+=	${PKGDIR}/PLIST.${OS_KERNEL}
    PLIST_SRC+=	${PKGDIR}/PLIST.${OPSYS}
    PLIST_SRC+=	${PKGDIR}/PLIST.${MACHINE_ARCH}
    PLIST_SRC+=	${PKGDIR}/PLIST.${OPSYS}-${MACHINE_ARCH}
    PLIST_SRC+=	${PKGDIR}/PLIST
\end{verbatim}
   If a Makefile sets {\tt PLIST\_SRC}, the defaults are not used.

   \smallbreak
   \item[DYNAMIC\_PLIST\_DIRS]
   A list of directories, absolute or relative to the installation
   {\tt\$\{PREFIX\}}, whose contents are dynamically added to the final packing
   list. This is useful to handle non-deterministic packing lists, most notably
   those generated by {\tt doxygen}. This should be used with care, since {\tt
   DYNAMIC\_PLIST\_DIRS} somewhat defeats the purpose of the packing list.

   \smallbreak  \item[PLIST\_SUBST]
   The {\tt  PLIST} file(s) of a  package may also  contain variable references
   (in the  {\tt\$\{VAR\}} form)  that are expanded  at intallation  time.  The
   following variables are supported by default:
\begin{verbatim}
	PKGBASE
	PKGNAME
	PKGVERSION

	OPSYS
	OS_VERSION
	OS_KERNEL
	OS_KERNEL_VERSION

	PKGMANDIR
	PKGINFODIR

	PLIST.<opt> # for all supported options
	PLIST.no<opt>
\end{verbatim}
   {\tt PLIST.<opt>} is special: one such variable is defined for each
   supported build option of the package. It can be used to dynamically enable
   an entry of the packing list, depending on the build options configuration.
   A {\tt\$\{PLIST.<opt>\}} variable may only be present only at the beginning
   of a line. Technically, {\tt\$\{PLIST.<opt>\}} expands to a packing list
   comment {\tt @comment} when the option {\tt <opt>} is not enabled, and to
   the empty string otherwise.

   {\tt PLIST.no<opt>} is similar to {\tt PLIST.<opt>}, but it enables a {\tt
   PLIST} entry only if the corresponding option is not enabled.

   Other substitutions may be added by adding definitions to the {\tt
   PLIST\_SUBST} variable. For instance, a package may define the {\tt FOO}
   variable substitution like so:
\begin{verbatim}
	PLIST_SUBST+= FOO=${FOO}
\end{verbatim}
   This would instruct the packing list generator to replace all occurences of
   {\tt\$\{FOO\}} by the value of the {\tt\$\{FOO\}} variable in the Makefile.

   \smallbreak
   \item[GENERATE\_PLIST]
   A sequence of commands, terminating in a semicolon, that outputs contents
   for a PLIST to stdout and is appended to the contents of
   {\tt\$\{PLIST\_SRC\}}. The default works for almost all packages, and it is
   usually not needed to define a custom command.

   \smallbreak
   \item[PLIST\_FILTER]
   A sequence of commands, each starting with a pipe, that filter out the
   packing list. This is to be used only in rare situations, and a standard
   package should not need to customize this.

\end{description}


\subsection{Customizing the semi-automatic PLIST generation} % -------------
\label{section:genvars:print-PLIST}

The semi-automatic  initial PLIST generation  does not handle  package options.
If  the  list  of  installed  files  depends  on  the  package  build  options,
{\tt\$\{PLIST.<opt>\}}       variable       references,       detailed       in
\xref{section:genvars:PLIST}{section~\ref{section:genvars:PLIST}},    must   be
manually added to the result of {\tt make print-PLIST}.


\subsection{Incrementing versions when fixing an existing package} % -------
\label{section:genvars:PKGREVISION}

When making fixes to an existing package it can be useful to change the version
number in {\tt PKGNAME}. To avoid conflicting with future versions by the
original author, a "r1", "r2", ... suffix can be used on package versions by
setting {\tt PKGREVISION=1} ({\tt 2}, ...) in the package Makefile. E.g.
\begin{quote}
   DISTNAME=             foo-17.42\\
   PKGREVISION=          9
\end{quote}
will result in a {\tt PKGNAME} of "foo-17.42r9". The "r" is treated like a "."
by the package tools.

{\tt PKGREVISION} should be incremented for any non-trivial change in the
resulting binary package. Without a {\tt PKGREVISION} bump, someone with the
previous version installed has no way of knowing that their package is out
of date. Thus, changes without increasing {\tt PKGREVISION} are essentially
labeled "this is so trivial that no reasonable person would want to
upgrade", and this is the rough test for when increasing {\tt PKGREVISION}
is appropriate. Examples of changes that do not merit increasing {\tt
PKGREVISION} are:
\begin{itemize}
   \item Changing {\tt HOMEPAGE}, {\tt MAINTAINER} or comments in Makefile.
   \item Changing build variables if the resulting binary package is the same.
   \item Changing {\tt DESCR}.
   \item Adding {\tt PKG\_OPTIONS} if the default options don't change.
\end{itemize}

Examples of changes that do merit an increase to {\tt PKGREVISION} include:
\begin{itemize}
   \item Security fixes
   \item Changes or additions to a patch file
   \item Changes to the {\tt PLIST}
   \item A dependency is changed or renamed.
\end{itemize}

{\tt PKGREVISION} must also be incremented when dependencies have ABI changes.

When a new release of the package is released, the {\tt PKGREVISION} must be
removed.


\subsection{Substituting variable text in the package files} % -------------
\label{section:genvars:SUBST}

When you want to replace the same text in multiple files or when the
replacement text varies, patches alone cannot help. This is where the SUBST
framework comes in. It provides an easy-to-use interface for replacing text in
files. Example:
\begin{verbatim}
   SUBST_CLASSES+=           fix-paths
   SUBST_STAGE.fix-paths=    pre-configure
   SUBST_MESSAGE.fix-paths=  Fixing absolute paths.
   SUBST_FILES.fix-paths=    src/*.c
   SUBST_SED.fix-paths=      -e 's,"/usr/local,"${PREFIX},g'
\end{verbatim}

{\tt SUBST\_CLASSES}  is a list  of identifiers that  are used to  identify the
different {\tt  SUBST} blocks  that are defined.  The {\tt SUBST}  framework is
used by  \robotpkg{}, so it  is important to  always use the {\tt  +=} operator
with this variable. Otherwise some substitutions may be skipped.

The remaining  variables of each {\tt  SUBST} block are  parameterized with the
identifier from the first line ({\tt fix-paths} in this case).

{\tt SUBST\_STAGE.*}  specifies the  stage at which  the replacement  will take
place. All combinations  of pre-, do- and post- together with  a phase name are
possible, though only few are  actually used. Most commonly used are post-patch
and pre-configure. Of these two, pre-configure should be preferred because then
it is possible  to run {\tt make  patch} and have the state  after applying the
patches but before making any other changes. This is especially useful when you
are debugging  a package  in order  to create new  patches for  it.  Similarly,
post-build  is preferred  over pre-install,  because the  install  phase should
generally be kept as simple as  possible. When you use post-build, you have the
same files  in the working directory that  will be installed later,  so you can
check if the substitution has succeeded.

{\tt  SUBST\_MESSAGE.*} is an  optional text  that is  printed just  before the
substitution is  done.

{\tt SUBST\_FILES.*} is the list  of shell globbing patterns that specifies the
files in which the substitution  will take place.  The patterns are interpreted
relatively  to the {\tt WRKSRC}  directory.

{\tt SUBST\_SED.*}  is a  list of  arguments to {\tt  sed(1)} that  specify the
actual substitution.  Every sed command should be prefixed with -e, so that all
{\tt SUBST} blocks look uniform.

There are some more variables, but they are so seldomly used that they are only
documented in the mk/internal/subst.mk file.
